*L'interface graphique

L'interface de mon programme est ralise sur la base d'un QGraphicsView, qui constitue ma fentre principale. Lorsqu'il est redimensionn, les lments qu'il contient le sont aussi. En particulier, la fractale affiche "en grand" est zoome automatiquement pour occuper toute la place disponible, ainsi que les vignettes. Celles-ci deviennent plus petites quand leur nombre augmente. La fentre a une taille minimale pour viter les effets dsastreux d'une fentre trop rduite.
J'utilise une QGraphicsScene pour y placer (et dplacer) les diffrents lments de mon interface, comme les boutons, le texte, les vignettes, et les fractales elles-mmes. Des effets d'animations de ces objets sont prvus ( base d'une QStateMachine et de groupes d'animation), mais je les ai dsactivs pour l'instant parce que les effets ne correspondaient pas encore  mes attentes.
Les boutons sont bass sur des QGraphicsWidget et ragissent aux clicks et survols (hover). Ils contiennent un QPixmap pour le "+" qu'ils contiennent. Plus tard, d'autres boutons prendront place sur la droite (Pause, Stop, enregistrer,...).
Finalement, chaque fractale est un CFractalPixmap (voir plus bas), affich en mode vignette (Preview) ou "en grand" (Full). Ces objets devraient tre cliquables, pour pouvoir passer de l'une  l'autre et changer les rglages, mais les clicks ne sont pas encore grs correctement.


*Les fractales (CFractalPixmap)

Mes CFractalPixmap sont des objets drivs des QGraphicsPixmapItem.
Ils peuvent donc tre placs et dplacs sur une scne, et recevoir des vnements souris ou clavier, ainsi qu'tre interconnects par SIGNAL/SLOT aux autres objets.
Ils contiennent un QPixmap pour l'affichage.
L'image de la fractale est place dans un QImage unique, qui est redimensionn pour un affichage "en grand" ou en vignette. La barre de progression y est directment dessine aussi.
Une fractale est dfinie par un struct "FractalSettings", qui contient le type, les coordonnes, le nombre de points, d'irrations max, etc... Une tableau de constantes est cr dans "settingsDialog" pour les rglages par dfaut pour chaque type de fractale.
Afin de grer le multithreading, je dcoupe ma fractale en un ensemble de sous-fractales (sub), dfinies par un struct "SubDefinition".
Le dcoupage d'une fractale de taille Width*Height en subStepX*subStepY sous-fractales est effectu suivant les 2 axes de la manire suivante:
- Chaque sous-fractale a la mme taille (dans le plan complexe) que la fractale elle-mme, mais contient seulement Width/subStepX points selon X et Height/subStepY suivant Y. Donc la sous-fractale a donc simplement un pas (dans le plan complexe) plus grand entre deux points de l'image.
- Chaque sous-fractale est dfinie par son offset (en nombre de points) en X et Y par rapport au point (0,0) de l'image.
- Chacune d'entre elle peut tre utilise pour un affichage en faible rsolution de la "fractale-mre".
- La combinaison de plusieurs sous-fractales permet, par interpolation, d'obtenir une image progressivement plus dfinie de la fractale-mre, par tesselation de Dirchlet, par exemple (non implment encore).
- Une fois toutes les sous-fractales calcules, on les recombine pour afficher la fractale entire.

Exemple: fractale de 1000*800 points, avec une division de 4*4 sous-fractales. Les sous fractales calcules contiendront respectivement les points suivants:
Sous-fractale (0,0):
(0,0), (4,0), (8,0)...
(0,4), (4,4), (8,4)...
...
(0,796),(4,796),(8,796)...

Sous-fractale (0,1):
(0,1), (4,1), (8,1)...
(0,1), (4,5), (8,5)...
...
(0,797),(4,797),(8,797)...

...
Sous-fractale (m,n):
(m,n), (m+4,n), (m+8,n)...
(m,n+4), (m+4,n+4), (m+8,n+4)...
...
(m,n+796),(m+4,n+796),(m+8,n+796)...

Avec m et n dans [0..3].

De cette manire, on peut partager le travail de manire efficace pour le moteur de multithreading. 
A priori, cela devrait permettre un affichage progressif et continu de la fractale durant son calcul. Je n'ai pas encore totalement rsolu ce problme, malheureusement, mais la structure est en place.


*Multithreading:

J'utilise la mthode "mappedReduced" pour sa gestion efficace des threads. 
J'ai une liste de dfinitions de sous-fractales en entre, et j'utilise les fonctions statiques "doCalculate()" et "doPostProcess" pour faire le mapping et la rduction.
Pour une fractale classique (Mandelbrot,...), doCalculate retourne dans un "SubResult" un vecteur contenant tous les points calculs pour la sous-fractale, plus sa dfinition.
Dans le cas d'une mthode d'accumulation (Buddhabrot), le vecteur retourn contient une liste de coordonnes  incrmenter (voir plus bas).
Dans les 2 cas, la fonction "doPostProcess" sait grer les donnes, et reconstitue l'image adquate dans un tableau unique. 
"mappedReduced" gre  merveille les accs concurrents  "doPostProcess" (une excution  la fois, contrairement  "doCalculate) , et sait optimiser au mieux les appels successifs aux 2 fonctions, avec les mises en attente appropries. 
Le rsultat est accessible via le "futureWatcher", et les mises  jours de la barre de progression sont gres  l'aide des signaux qu'il met durant la progression. (Pas encore clair: comment accder aux rsultats avant la fin de l'ensemble, de manire sre, sans jamais faire planter le programme ?!?!?)


*Buddhabrot:

- Gnration de points alatoires: Je gnre 2 listes (randomVector1 et randomVector2) relativement courtes de nombres alatoires, de taille M et M+1, que je parcours en boucle. Chaque valeur de cette liste ne correspond pas  une coordonne, mais  une "perturbation" (deltaX et deltaY), i.e. un petit nombre alatoire, infrieur  la taille d'un pixel, ajout  la coordonne. Ainsi, je peux parcourir mon plan complexe comme pour Mandelbrot, et utiliser mes 2 listes pour affecter des perturbations  mes coordonnes X  l'aide des lments de randomVector1 et Y  l'aide des lments de randomVector2. De par la diffrence de taille de ces listes, je ne retrouverai la mme combinaison de deltaX et deltaY qu'aprs M*(M+1) points, mais en ayant gnr uniquement 2M+1 points alatoires !! Optimisation!!
- Accumulation: Une fois mon point C dtermin, je calcule la srie Zn de manire classique, mais je stocke ses valeurs dans un tableau (zBuffer). Si la srie ne s'"chappe" pas (i.e. fait partie de l'ensemble de Mandelbrot), je ne fais rien de cette liste, et je passe au point suivant. Dans le cas contraire, je convertis alors les valeurs de cette suite en coordonnes d'image, et je rajoute cette liste de coordonnes  mon vecteur-rsultat. De cetet manire, je n'ai pas  calculer 2x les points Zn!! Optimisation !!
- Une fois tous les points de la sous-fractale calculs, on se retrouve avec une longue liste de coordonnes. La fonction de PostProcessing n'a plus alors qu' incrmenter tous les points de l'image dont les coordonnes sont contenues dans la liste, et ce pour chacune des sous-fractales.
- N.B.: les coordonnes sont constitues d'un seul entier, car l'image est considre comme un tableau  1 dimension, o tous les pixels sont mis bout  bout. On conomise ainsi de la mmoire lors du stockage des points  incrmenter: 1 entier par incrment au lieu de 2. La mmoire ncessaire pour cette liste est libre automatiquement  la fin du traitement de chaque sous-fractale, donc il n'y a pas d'utilisation excessive de la mmoire. Seules les donnes pour les sous-fractales en cours  un instant donn (= nombre de coeurs) sont en mmoire.
- Afin d'obtenir un nombre de points suffisants pour gnrer le Buddhabrot, j'ai implment un entier "repeatAll", qui est utilis pour dupliquer d'autant le nombre de sous-fractales. Par exemple, avec une fractale de 1000x1000 points, decoupe en 4x4 sous fractales, et repeatAll = 50, on aura 50*1000*1000 points gnrs, rpartis dans 50*4*4 = 800 sous-fractales. (Ce qui permet, pour un affichage "Live", d'afficher jusqu' 800 tapes intermdaires pour la fractale complte!!).